<?php
declare (strict_types=1);

namespace app\common\logic\category\admin;

use app\common\exception\LogicException;
use app\common\model\category\admin\Category as CategoryModel;

/**
 * 分类逻辑层
 */
class Category extends CategoryModel
{
    /**
     * 分类数据
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-03-24
     */
    public function getList($pid = 0)
    {
        $type     = $this->getCategoryType(0);
        $category = $this->where('category_type', $type)->where('pid', $pid)->order('sort')->select();
        if ($category) {
            foreach ($category as $cate) {
                $cate->hasChildren = $this->hasChildren($cate->id);
            }
        }

        return $category;
    }

    /**
     * 是否有子集
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-03-24
     */
    public function hasChildren(int $pid = 0): bool
    {
        return $this->where('pid', $pid)->find() ? true : false;
    }

    /**
     * 创建分类
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-03-24
     *
     * @param array $data [description]
     */
    public function createCategory(array $data)
    {
        // 验证数据
        $this->getValidate()->scene('add')->failException()->check($data);
        // 当前父级分类最大sort值
        $sort  = $this->getMaxSortByPid($data['pid']);
        $sort  = intval($sort) + 1;
        $level = $data['pid'] ? $this->getParentLevel($data['pid']) : 0;
        // $data['sort']  = $sort + 1;
        // $data['level'] = $level + 1;

        $saved  = [];
        $titles = explode("\n", $data['title']);
        foreach ($titles as $key => $title) {
            $sort    = $sort + $key;
            $saved[] = [
                'title' => $title,
                'sort'  => $sort,
                'level' => $level + 1,
                'pid'   => $data['pid'] ?? 0
            ];
        }

        return $this->saveAll($saved);
    }

    /**
     * 编辑分类
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-03-24
     */
    public function editCategory(array $data)
    {
        // 验证数据
        $this->getValidate()->scene('edit')->failException()->check($data);
        $that = $this->findOrEmpty($data['id']);
        if ($that->isEmpty()) {
            throw new LogicException('分类不存在');
        }
        $that->title = $data['title'];
        $that->save();
        return $that;
    }

    /**
     * 删除分类
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-03-24
     */
    public function deleteCategory($id)
    {
        $that = $this->findOrEmpty($id);
        if ($that->isEmpty()) {
            throw new LogicException('分类不存在');
        }
        // 是否有子级
        if ($this->hasChildren($that->id)) {
            throw new LogicException('存在子分类，不可删除');
        }
        return $that->delete();
    }

    /**
     * 最大排序值
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-05-18
     *
     * @param integer $pid [description]
     * @return   [type]                              [description]
     */
    public function getMaxSortByPid($pid = 0)
    {
        return $this->where('pid', $pid)->max('sort') ?: 0;
    }

    /**
     * 获取上级level
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date 2022-03-21
     *
     * @param integer $id [description]
     * @return [type]      [description]
     */
    public function getParentLevel($id = 0)
    {
        return $this->where('id', $id)->value('level') ?: 0;
    }

    /**
     * 无限极分类
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-05-18
     *
     * @param integer $pid [description]
     * @return   [type]                              [description]
     */
    public function cascaderCate($pid = 0, $type = 0, $mhmId = 0)
    {
        $this->autoCheckUsePublic();
        $type = $this->getCategoryType($type);
        if ($mhmId) {
            $builder = $this->withoutGlobalScope(['mhm'])->where('pid', $pid)->where('mhm_id', $mhmId)->where('category_type', $type);
        } else {
            $builder = $this->where('pid', $pid)->where('category_type', $type);
        }

        $cate = $builder->order('sort')->field('id as value,title as label')->select();
        if ($cate) {
            foreach ($cate as &$c) {
                $child = $this->cascaderCate($c['value'], $type, $mhmId);
                $child && $c['children'] = $child;
            }
            unset($c);
        }

        return $cate->toArray();
    }

    /**
     * 无限极分类
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-05-18
     *
     * @param integer $pid [description]
     * @return   [type]                              [description]
     */
    public function cascader(int $pid = 0, int $type = 0, int $mhmId = 0)
    {
        if ($mhmId) {
            $cate = $this->withoutGlobalScope(['mhm'])->where('pid', $pid)->where('mhm_id', $mhmId)->where('category_type', $type)->order('sort')->field('id as value,title as label')->select();
        } else {
            $cate = $this->where('pid', $pid)->where('category_type', $type)->order('sort')->field('id as value,title as label')->select();
        }

        if (!$cate->isEmpty()) {
            foreach ($cate as &$c) {
                $child = $this->cascader($c['value'], $type, $mhmId);
                $child && $c['children'] = $child;
            }
            unset($c);
        }

        return $cate->toArray();
    }

    /**
     * 一级分类下拉列表
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-05-18
     *
     * @param integer $pid [description]
     * @return   [type]                              [description]
     */
    public function topList(int $type = 0)
    {
        return $this
            ->where('pid', 0)
            ->where('category_type', $type)
            ->order('sort')
            ->field('id as value,title')
            ->select()->toArray();
    }

    /**
     * 课程平台分类无限极结构
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-08-27
     *
     * @param integer $pid  [description]
     * @param integer $type [description]
     * @return   [type]                               [description]
     */
    public function platformCascaderCate($pid = 0, $type = 0)
    {
        $this->autoCheckUsePublic();
        $type = $this->getCategoryType($type);
        $cate = $this->withoutGlobalScope(['mhm'])
            ->where('pid', $pid)
            ->where('mhm_id', 1)
            ->where('category_type', $type)
            ->order('sort')
            ->field('id as value,title as label')
            ->select();
        if ($cate) {
            foreach ($cate as &$c) {
                $child = $this->platformCascaderCate($c['value'], $type);
                $child && $c['children'] = $child;
            }
            unset($c);
        }

        return $cate->toArray();
    }

    /**
     * 解析分类名称
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-06-03
     *
     * @return   [type]                         [description]
     */
    public function parseTitle(?array $fullcategorypath = [])
    {
        $titles = [];
        if (!empty($fullcategorypath)) {
            foreach ($fullcategorypath as $v) {
                $items    = $this->withoutGlobalScope(['categoryType'])->whereIn('id', $v)->removeOption('soft_delete')->column('title');
                $titles[] = implode('/', $items);
            }
        }

        return $titles;
    }

}
